#include "gtest/gtest.h"

#include "Helper.h"

#include "rocksdb/db.h"
#include "rocksdb/options.h"
using namespace std;
using namespace rocksdb;


class SingleOperationTest : public testing::Test {
public:
    void SetUp() override{
        db = helper.createDb(name);
    }
    void TearDown() override{
        db->Close();
        db.reset();
    }
protected:
    std::shared_ptr<rocksdb::DB> db;
    const std::string name = "./test.db";
    Helper helper;
};


TEST_F(SingleOperationTest, test){
    ASSERT_TRUE(db != nullptr);

    std::string expect = "world2";
    const std::string key("hello");
    ASSERT_TRUE(db->Put(rocksdb::WriteOptions(), key, expect).ok());

    std::string dbValue;
    ASSERT_TRUE(db->Get(rocksdb::ReadOptions(), key, &dbValue).ok());
    ASSERT_EQ(expect, dbValue);

    ASSERT_TRUE(db->Delete(rocksdb::WriteOptions(), key).ok());

    auto s = db->Get(rocksdb::ReadOptions(), key, &dbValue);
    ASSERT_TRUE(s.IsNotFound());
}

TEST_F(SingleOperationTest, testIterator){
	ASSERT_TRUE(db->Put(rocksdb::WriteOptions(), "hello0", "world0").ok());
	ASSERT_TRUE(db->Put(rocksdb::WriteOptions(), "hello1", "world1").ok());
	ASSERT_TRUE(db->Put(rocksdb::WriteOptions(), "hello2", "world2").ok());
	ASSERT_TRUE(db->Put(rocksdb::WriteOptions(), "hello3", "world3").ok());
	ASSERT_TRUE(db->Put(rocksdb::WriteOptions(), "hello4", "world4").ok());
	ASSERT_TRUE(db->Put(rocksdb::WriteOptions(), "hello5", "world5").ok());

	rocksdb::Iterator * iter = db->NewIterator(rocksdb::ReadOptions());
	ASSERT_TRUE(iter != nullptr);
	size_t count = 0;
	for(iter->SeekToFirst(); iter->Valid(); iter->Next()){
		count++;	
	}
	ASSERT_EQ(6ull, count );
}

